/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package algoritmo2;

import algoritmo2.tipos.InfoNodo;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;

/**
 *
 * @author Ra
 */
public class RandomPropio {

    private static final Random random = new Random();

    public static boolean boolRandom() {
        double booleano = Math.random();
        if(booleano > 0.5){
            return false;
        }
        return true;
        //return random.nextBoolean();
    }

    public static int intRandom(int primer, int ultimo) {
        int aux = 0;
        try {
            aux = random.nextInt(ultimo - primer);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return primer + aux;

    }

    public static ArrayList<InfoNodo> preorden(Arbol arb) {
        // El recorrido en preorden es raíz, hijo izquierdo, hijo derecho
        ArrayList<InfoNodo> listaNodos = new ArrayList<InfoNodo>();
        InfoNodo info = new InfoNodo();
        info.setNombre(arb.getNombre());
        info.setArbol(arb);
        if (arb.isHoja() || arb.isRaiz()) {
            info.setEsHoja(true);
        }

        listaNodos.add(info);
        if (arb.getRamaCondicionIf() != null) {
            listaNodos.addAll(preorden(arb.getRamaCondicionIf()));
        }
        if (arb.getHi() != null) {
            listaNodos.addAll(preorden(arb.getHi()));
        }

        if (arb.getHd() != null) {
            listaNodos.addAll(preorden(arb.getHd()));
        }

        return listaNodos;
    }

    public static Arbol dameNodo(ArrayList<InfoNodo> listaNodos) {
        // Lo primero creamos una lista con el recorrido en preorden del árbol

        List<InfoNodo> listaRaizHojas = new ArrayList<InfoNodo>();
        List<InfoNodo> listaNodosIntermedios = new ArrayList<InfoNodo>();

        for (InfoNodo info : listaNodos) {
            if (info.isEsHoja()) {
                listaRaizHojas.add(info);
            } else {
                listaNodosIntermedios.add(info);
            }
        }
        double prob = Math.random();
        
        int valor;
        InfoNodo infoNodoElegido;
        if (prob > 0.9) {
            //cogemos un nodo de la lista de hojas y raiz
            valor = intRandom(0, listaRaizHojas.size());
            infoNodoElegido = listaRaizHojas.get(valor);

        } else {
            //cogemos un nodo de la lista de nodos intermedios
            if (listaNodosIntermedios.size() == 0) {
                valor = intRandom(0, listaRaizHojas.size());
                infoNodoElegido = listaRaizHojas.get(valor);
            } else {
                valor = intRandom(0, listaNodosIntermedios.size());
                infoNodoElegido = listaNodosIntermedios.get(valor);
            }
        }
        return infoNodoElegido.getArbol();
    }

    public static Arbol dameNodo(Individuo padre1Clon) {
        // Lo primero creamos una lista con el recorrido en preorden del árbol
        ArrayList<InfoNodo> listaNodos = new ArrayList<InfoNodo>();
        listaNodos = preorden(padre1Clon.getArbol());
        for (int i = 0; i < listaNodos.size(); i++) {
            InfoNodo info = listaNodos.get(i);
            info.setPosLista(i);
        }
        List<InfoNodo> listaRaizHojas = new ArrayList<InfoNodo>();
        List<InfoNodo> listaNodosIntermedios = new ArrayList<InfoNodo>();

        for (InfoNodo info : listaNodos) {
            if (info.isEsHoja()) {
                listaRaizHojas.add(info);
            } else {
                listaNodosIntermedios.add(info);
            }
        }
        double prob = Math.random();
        int valor;
        InfoNodo infoNodoElegido;
        if (prob < 0.1) {
            //cogemos un nodo de la lista de hojas y raiz
            valor = intRandom(0, listaRaizHojas.size());
            infoNodoElegido = listaRaizHojas.get(valor);

        } else {
            //cogemos un nodo de la lista de nodos intermedios
            if (listaNodosIntermedios.size() == 0) {
                valor = intRandom(0, listaRaizHojas.size());
                infoNodoElegido = listaRaizHojas.get(valor);
            } else {
                valor = intRandom(0, listaNodosIntermedios.size());
                infoNodoElegido = listaNodosIntermedios.get(valor);
            }
        }
        return infoNodoElegido.getArbol();
    }

    public static Arbol dameNodoFuncional(Individuo padre1) {
        ArrayList<InfoNodo> listaNodos = new ArrayList<InfoNodo>();
        listaNodos = preorden(padre1.getArbol());
        for (int i = 0; i < listaNodos.size(); i++) {
            InfoNodo info = listaNodos.get(i);
            info.setPosLista(i);
        }
        List<InfoNodo> listaRaizHojas = new ArrayList<InfoNodo>();
        List<InfoNodo> listaNodosIntermedios = new ArrayList<InfoNodo>();

        for (InfoNodo info : listaNodos) {
            if (info.isEsHoja()) {
                listaRaizHojas.add(info);
            } else {
                listaNodosIntermedios.add(info);
            }
        }
        //TODO:comprobar si mete la raiz
        listaNodosIntermedios.add(listaRaizHojas.get(0));

        int valor;
        InfoNodo infoNodoElegido;

        //cogemos un nodo de la lista de nodos intermedios
        valor = intRandom(0, listaNodosIntermedios.size());
        infoNodoElegido = listaNodosIntermedios.get(valor);

        return infoNodoElegido.getArbol();
    }

    public static Arbol dameNodoTerminal(Individuo padre1) {
        // Lo primero creamos una lista con el recorrido en preorden del árbol
        ArrayList<InfoNodo> listaNodos = new ArrayList<InfoNodo>();
        listaNodos = preorden(padre1.getArbol());
        for (int i = 0; i < listaNodos.size(); i++) {
            InfoNodo info = listaNodos.get(i);
            info.setPosLista(i);
        }
        List<InfoNodo> listaRaizHojas = new ArrayList<InfoNodo>();
        List<InfoNodo> listaNodosIntermedios = new ArrayList<InfoNodo>();

        for (InfoNodo info : listaNodos) {
            if (info.isEsHoja()) {
                listaRaizHojas.add(info);
            } else {
                listaNodosIntermedios.add(info);
            }
        }
        //TODO: Mirar si quitamos la raiz
        if (listaRaizHojas.size() > 1) {
            listaRaizHojas.remove(0);
        }

        int valor;
        InfoNodo infoNodoElegido = null;

        //cogemos un nodo de la lista de hojas y raiz
        try {
            valor = intRandom(0, listaRaizHojas.size());
            infoNodoElegido = listaRaizHojas.get(valor);
        } catch (Exception e) {
            System.out.println(padre1.getArbol());
            e.printStackTrace();
            ;
        }


        return infoNodoElegido.getArbol();
    }
}
